<template>
  <!-- <img alt="Vue logo" src="./assets/logo.png"> -->
  <MyInput v-model:value="value" />
  <span>{{ value }}</span>
  <!-- <input type="text" v-model="value"> -->
  <HelloWorld :msg="title" @changeTitle="changeTitle" v-slot="slotProps">
    <li>
      <span>{{ slotProps.item }}-{{ slotProps.index }}</span>
    </li>
  </HelloWorld>
  <div>{{ name }}</div>
  <div>{{ (typeof count) }}</div>
  <input type="text" v-model="count" @keydown.enter="handleDown">
  <ul>
    <li v-for="item in obj" :key="item">{{ item }}</li>
  </ul>
  <ol>
    <li v-for="item in arr" :key="item">{{ item }}</li>
  </ol>
  <button @click="handleObj">change</button>
  <KeepAlive>
    <component :is="componentName" />
  </KeepAlive>
  <div id="main"></div>
  <Teleport to="#main">
    <button @click="changeName">传送门</button>
  </Teleport>
  <input type="text" v-focus>
  <button class="position" v-pos:left="top">位置</button>
  <button class="position" v-pos="top1">位置1</button>
  <span>{{ number }}</span>
  <span>总价{{ totalPrice }}</span>
</template>

<script>
// 指令
// v-for v-if v-show v-bind(:) v-html v-model v-text v-on(@) v-slot(#)

// 修饰符
// 事件修饰符 once、self、stop、prevent、capture
//  v-model 修饰符 lazy(失焦，数据改变)、trim、number(数据转为number)
// 按键修饰符 .enter

// 组件
// 插槽
// 默认插槽 直接在子组件使用slot标签

// 具名插槽 
// 1. 插槽起名 v-slot:name / #name
// 2. 子组件slot标签添加name属性

// 作用域插槽
// 1. 子组件slot标签绑定需要传递的数据,可传多个
// 2. 父组件消费：在父组件调用的子组件标签上，使用v-slot="props",接收子组件传递的参数对象
// 在插槽中即可使用子组件传递的值

// 动态组件
// component内置标签，动态绑定is属性，is的值可以为任意标签（可在template中正常渲染）
// <component :is="componentName" />

// Teleport内置组件，传送门，to属性可以传送到任意dom位置

// mixin 混入,逻辑混入
// 可以对逻辑进行抽离，实现逻辑的复用
// 1. 单独声明mixin，是一个对象，包括vue的options参数
// 2. 注册，组件内使用mixins: [mixin]
// data、methods中组件优先级高于mixin
// 生命周期，mixin先执行

// 自定义指令，全局/局部
// 组件加v-xxx

// 组件app.component 全局注册组件


// 插件
// 集合，根据某个业务功能， 组件、指令、逻辑

// 生命周期
// destory -> unmount
// setup

// v-model
// 自定义组件实现v-model
// 1. 在组件上绑定v-model:name属性
// 2. 在子组件props中注册modelValue(固定,默认modelValue)
// 3. 在对应子组件控件上绑定value属性，实现数据改变，视图改变
// 4. 在对应子组件上添加绑定change事件，此时调用update:modelValue(固定，默认modelValue)，传入新值，实现父组件值的更新

// 数据劫持原理不同
import HelloWorld from './components/HelloWorld.vue'
import MyInput from './components/my-input.vue'
// import directives from './direactive'
// import myMixin from './mixin/myMixin'
// const componentMap = ['input', 'button', 'div']


export default {
  name: 'App',
  components: {
    HelloWorld,
    MyInput
  },
  // mixins: [myMixin],
  data() {
    return {
      value: '123',
      name: 'tom',
      obj: {
        a: 1
      },
      count: 2,
      price: 3,
      arr: [1, 2, 3],
      title: '父组件title',
      componentName: 'button',
      top: 100,
      top1: 200,
      number: 2,
      // totalPrice: 0
    }
  },
  methods: {
    handleObj() {
      // this.obj.b = 1
      // this.arr[0] = 0
      if (this.componentName === 'button') {
        this.componentName = 'input'
      } else {
        this.componentName = 'button'
      }

    },
    handleDown() {
      console.log('down')
    },
    changeTitle(title) {
      this.title = title
    },
    changeName() {
      console.log('app fn')
    }
  },
  // directives,
  mounted() {
    console.log('app mount', this)
    // setTimeout(() => {
    //   this.count++
    // }, 1000)
    // setTimeout(() => {
    //   this.top = 300
    // }, 3000)
    // console.log(this, 'this')
  },
  watch: {
    count() {
      this.totalPrice = this.count * this.price
    },
    price() {
      // console.log('123')
      this.totalPrice = this.count * this.price
    },
  },
  computed: {
    totalPrice() {
      return this.count * this.price
    }
  },
  // watch监听 - 单个监听 - 惰性监听，初始化不会自动执行
  // computed 监听-计算属性 - 可以识别其中多个依赖，实现多个依赖的监听；初始化就会自动执行
  // computed return 计算出的值，template、this访问
  // watch 监听，里面执行函数，当值发生变化，去执行内部的handler处理函数
  // 购物车， 全选状态，总计computed

  // provide/inject  非响应式

  // v-model vue3增强
  provide: {
    name: 'tom'
  }
} 
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}

.position {
  position: fixed;
  top: 0;
  left: 0;
}
</style>
